#include <iostream>
#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include "BlockQueue.hpp"
using namespace std;

#define PLATESIZE 10
#define PRODUCERSIZE 5
#define CONSUMERSIZE 4

BlockingQueue<int> bq(10);

void* producer(void* args)
{
    string* name = static_cast<string*>(args);
    for(int i = 0; i < 10; i++)
    {
        int weight = rand() % 9 + 1;
        bq.push(weight);
        printf("[生产者%s]向盘中放入一个重%dkg的苹果\n", name->c_str(), weight);
    }
    return nullptr;
}

void* consumer(void* args)
{
    string* name = static_cast<string*>(args);
    while(true)
    {
        int weight = bq.pop();
        printf("[消费者%s]从盘中取出一个重%dkg的苹果\n", name->c_str(), weight);
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr));
    vector<pair<pthread_t, string>> producers(PRODUCERSIZE);
    for(int i = 0; i < PRODUCERSIZE; i++)
    {
        producers[i].second = "Thread-" + to_string(i);
        pthread_create(&producers[i].first, nullptr, producer, &producers[i].second);
    }
    std::vector<pair<pthread_t, string>> consumers(CONSUMERSIZE);
    for(int i = 0; i < CONSUMERSIZE; i++)
    {
        consumers[i].second = "Thread-" + to_string(i + PRODUCERSIZE);
        pthread_create(&consumers[i].first, nullptr, consumer, &consumers[i].second);
    }

    // 等待生产者退出
    for(int i = 0; i < PRODUCERSIZE; i++)
    {
        pthread_join(producers[i].first, nullptr);
    }

    // 等待苹果被完全取出
    while(!bq.empty())
    {
        usleep(100);
    }
    // 清理消费者
    for(int i = 0; i < CONSUMERSIZE; i++)
    {
        pthread_cancel(consumers[i].first);
    }

    return 0;
}